﻿
Imports System.IO
Imports std
Imports xmlctrl
Imports xhtmlctrl

Public MustInherit Class inlineResource
    Inherits container

    Private resource As map(Of String, map(Of String, String)) = Nothing
    Private Shared resourceBank As map(Of String, map(Of String, String)) = Nothing

    Shared Sub New()
        resourceBank = New map(Of String, map(Of String, String))()
    End Sub

    Public Sub New(Optional ByVal buff As Stream = Nothing)
        MyBase.New(buff)
        resource = New map(Of String, map(Of String, String))()
    End Sub

    Private Shared Function addresource(ByVal r As map(Of String, map(Of String, String)), _
                                        ByVal type As String, ByVal name As String, ByVal content As String) As Boolean
        assert(Not r Is Nothing)
        If Not isemptystring(type) AndAlso Not isemptystring(name) AndAlso Not isemptystring(content) Then
            SyncLock r
                Dim rtn As Boolean = True
                If isdebugmode() Then
                    If r(type).find(name) <> r(type).end() AndAlso Not strsame(r(type)(name), content) Then
                        Dim msg As String = Nothing
                        msg = "duplicate resource found, type " + type + ", name " + name + ", addresource failed."
                        If isdebugbuild() Then
                            debugassert(False, msg)
                        Else
                            raiseError(errorHandle.errorType.warning, msg)
                        End If
                        rtn = False
                    End If
                End If
                r(type)(name) = content
                Return rtn
            End SyncLock
            Return True
        Else
            Return False
        End If
    End Function

    Protected Function addresource(ByVal type As String, ByVal name As String, ByVal content As String) As Boolean
        Return addresource(resource, type, name, content)
    End Function

    Protected Shared Function registerResource(ByVal type As String, ByVal name As String, _
                                               ByVal content As String) As Boolean
        Return addresource(resourceBank, type, name, content)
    End Function

    Protected Function addRegisteredResource(ByVal type As String, ByVal name As String) As Boolean
        Dim i As map(Of String, map(Of String, String)).iterator = Nothing
        Dim rtn As Boolean = False
        SyncLock resourceBank
            i = resourceBank.find(type)
            If i <> resourceBank.end() Then
                Dim j As map(Of String, String).iterator = Nothing
                j = (+i).second.find(name)
                If j <> (+i).second.end() Then
                    addresource(type, name, (+j).second)
                    rtn = True
                End If
            End If
        End SyncLock

        Return rtn
    End Function

    Protected MustOverride Function generateInstance() As xhtmlControl

    Protected Function resourceContent(ByVal compress As Boolean) As String
        Dim s As String = Nothing
        Dim i As map(Of String, map(Of String, String)).iterator = Nothing
        i = resource.begin()
        While i <> resource.end()
            Dim j As map(Of String, String).iterator = Nothing
            j = (+i).second.begin()
            While j <> (+i).second.end()
                s += (+j).second
                If Not compress Then
                    s += newline.incode()
                End If
                j += 1
            End While
            i += 1
        End While

        Return s
    End Function

    Protected Function resourceContent() As String
        Return resourceContent(shouldCompress())
    End Function

    Public Shared Function resourceContent(ByVal ir As inlineResource) As String
        If ir Is Nothing Then
            Return Nothing
        Else
            Return ir.resourceContent()
        End If
    End Function

    Protected NotOverridable Overrides Function render(ByVal compress As Boolean) As Boolean
        children().clear()
        Dim i As map(Of String, map(Of String, String)).iterator = Nothing
        i = resource.begin()
        While i <> resource.end()
            Dim inst As xhtmlControl = Nothing
            inst = generateInstance()
            inst.type = (+i).first

            'add <!--
            Dim xmltext As xmltext = Nothing
            xmltext = New xmltext(textEncodingEnum.none, output())
            xmltext.text = comment.begin + newline.incode()
            inst.addchild(xmltext)

            Dim j As map(Of String, String).iterator = Nothing
            j = (+i).second.begin()
            While j <> (+i).second.end()
                xmltext = New xmltext(textEncodingEnum.none, output())
                If compress OrElse j = (+i).second.begin() Then
                    xmltext.text = (+j).second
                Else
                    xmltext.text = newline.incode() + (+j).second
                End If
#If RETIRED Then
                xmltext.text = (+j).second
#End If
                inst.addchild(xmltext)
                j += 1
            End While

            'add -->
            xmltext = New xmltext(textEncodingEnum.none, output())
            xmltext.text = newline.incode() + comment.end
            inst.addchild(xmltext)

            addchild(inst)
            i += 1
        End While

        Return MyBase.render(compress)
    End Function

    Public Overrides Sub clear()
        resource.clear()
        MyBase.clear()
    End Sub
End Class
